const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
	host: 'http://elastic.kedian.net',
	log: 'trace'
});
const Keys = require('../tools/keys')

module.exports.client = client;

const PERPAGE = 18;
const RECOMMS_NUMBER = 3;
const INDEX = 'course'
const TYPE = 'c'

module.exports.list = async (query) => {
	const searchObj = {
		index: INDEX,
		type: TYPE,
		from: query.offset,
		size: PERPAGE,
		body: {
			query: {
		    function_score: {
		      query: {
		        multi_match: {
		          query:query.q,
		          analyzer:"ik_max_word",
		          fields: [ "title^2", "subtile", "tags", "site" ]
		        }
		      },
		      script_score: {
		        script: "long ohitN=doc['o_hitN'].value;long hitN=doc['hitN'].value;long ostuN=doc['o_stuN'].value;long obookmarkN=doc['o_bookmarkN'].value;long bookmarkN=doc['bookmarkN'].value;long shareN=doc['shareN'].value;long total=ohitN+4*hitN+5*ostuN+10*(obookmarkN+4*bookmarkN)+20*(shareN*4); double orating=doc['o_rating'].value; long oratingN=doc['o_ratingN'].value; long rating=doc['rating'].value; long ratingN=doc['ratingN'].value; long admrating=doc['adm_rating'].value; double uScore = 0; if((oratingN+ ratingN)>10) { double scoreSum=(orating*10%+rating*20%+admrating*70); double div = 0; if(orating!=0) {div= div+ 0.1} if(rating!=0){div=div+0.2} if(admrating!=0){div=div+0.7} uScore=scoreSum/div} return ((uScore)*0.1+(1/(1+Math.pow(Math.E,(-1*total/200)))))*2 + _score"
		      }
		    }
		  }
		}
	}
	const result = await client.search(searchObj);
	const hasNext = query.offset + PERPAGE < result.hits.total;
	const hasPrevious = query.offset === 0;
	return {
		courses: result.hits.hits.map(hit => {
			return Object.assign(hit._source, {_id: hit._id});
		}),
		query: query,
		total: result.hits.total,
		hasNext,
		hasPrevious
	}
}

module.exports.findRecomms = async () => {
	const result = await client.search({
		index: INDEX,
		type: TYPE,
		size: RECOMMS_NUMBER,
		body: {
			query: {
		    function_score: {
		      query: {
		        multi_match: {
		          query: Keys.randomKey(),
		          analyzer: "ik_max_word",
		          fields: [ "title^2", "subtile", "tags", "site" ]
		        }
		      },
		      script_score: {
		        script: "long ohitN=doc['o_hitN'].value;long hitN=doc['hitN'].value;long ostuN=doc['o_stuN'].value;long obookmarkN=doc['o_bookmarkN'].value;long bookmarkN=doc['bookmarkN'].value;long shareN=doc['shareN'].value;long total=ohitN+4*hitN+5*ostuN+10*(obookmarkN+4*bookmarkN)+20*(shareN*4); double orating=doc['o_rating'].value; long oratingN=doc['o_ratingN'].value; long rating=doc['rating'].value; long ratingN=doc['ratingN'].value; long admrating=doc['adm_rating'].value; double uScore = 0; if((oratingN+ ratingN)>10) { double scoreSum=(orating*10%+rating*20%+admrating*70); double div = 0; if(orating!=0) {div= div+ 0.1} if(rating!=0){div=div+0.2} if(admrating!=0){div=div+0.7} uScore=scoreSum/div} return ((uScore)*0.1+(1/(1+Math.pow(Math.E,(-1*total/200)))))*2 + _score"
		      }
		    }
		  }
		}
	})
	return result.hits.hits.map(hit => {
			return Object.assign(hit._source, {_id: hit._id});
		})
}

module.exports.hit = async (id, user) => {
	await client.update({
		index: INDEX,
		type: TYPE,
		id: id,
		body: {
			script: 'if (!ctx._source.containsKey(\"hitN\")) { ctx._source.hitN = 1 } else { ctx._source.hitN+=1}',
			upsert: {
				hitN: 1
			}
		}
	})
}

module.exports.bookmark = async (id, user) => {
	await client.update({
		index: INDEX,
		type: TYPE,
		id: id,
		body: {
			script: 'if (!ctx._source.containsKey(\"bookmark\")) { ctx._source.bookmark = 1 } else { ctx._source.bookmark+=1}',
			upsert: {
				bookmark: 1
			}
		}
	})
}

module.exports.share = async (id, user) => {
	await client.update({
		index: INDEX,
		type: TYPE,
		id: id,
		body: {
			script: 'if (!ctx._source.containsKey(\"share\")) { ctx._source.share = 1 } else { ctx._source.share+=1}',
			upsert: {
				share: 1
			}
		}
	})
}